package com.peng.community.controller;

import com.peng.community.constant.CommunityConstant;
import com.peng.community.entity.*;
import com.peng.community.event.EventProducer;
import com.peng.community.service.CommentService;
import com.peng.community.service.DiscussPostService;
import com.peng.community.service.UserService;
import com.peng.community.service.impl.LikeService;
import com.peng.community.util.CommunityUtils;
import com.peng.community.util.HostHolder;
import com.peng.community.util.RedisKeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@Component
@Slf4j
@RequestMapping("/discuss")
public class DiscussPostController implements CommunityConstant {

    @Autowired
    HostHolder hostHolder;

    @Autowired
    DiscussPostService discussPostService;

    @Autowired
    EventProducer eventProducer;

    @Autowired
    RedisTemplate redisTemplate;

    @PostMapping("/add")
    @ResponseBody
    public String addDiscussPost(String title, String content) {

        final User user = hostHolder.getUser();
        if (user == null) {
            return CommunityUtils.toJsonString(403, "您还没有登录");
        }
        log.info("请求到来：title:{},content:{}", title, content);
        DiscussPost discussPost = new DiscussPost();
        discussPost.setTitle(title);
        discussPost.setContent(content);
        discussPost.setUserId(user.getId());
        discussPost.setCreateTime(new Date());

        discussPostService.insertDiscussPost(discussPost);


        //触发发帖事件
        Event event = new Event()
                .setTopic(TOPIC_PUBLISH)
                .setEntityType(ENTITY_TYPE_POST)
                .setEntityId(discussPost.getId())
                .setUserId(discussPost.getUserId());
        eventProducer.send(event);


        //在帖子热度分钟添加一个记录,作为初始分数依据
        //记录存储的值为帖子的id，可以进行去重
        String postScoreKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(postScoreKey, discussPost.getId());

        //其他属性默认为0
        return CommunityUtils.toJsonString(0, "发布成功！");
    }

    @Autowired
    UserService userService;

    @Autowired
    CommentService commentService;

//    @GetMapping("/detail/{id}")
//    //Page作为实体类会被SpringMVC请求到来时自动填充(POST)，响应时自动注入到Model中
//    public String getDiscussPostPage(@PathVariable("id") int id, Model model, Page page) {
//        //转到性情页，并携带帖子全部信息和用户全部信息
//        DiscussPost discussPost = discussPostService.findDiscussPostById(id);
//        //user信息也可以通过mybatis的关联查询得到；由于最后查询会转到redis，因此显然直接查效率更高
//        User user = userService.selectById(discussPost.getUserId());
//        model.addAttribute("post", discussPost);
//        model.addAttribute("user", user);
////        log.info("user:{}, post:{}",user.toString(), discussPost.toString());
//
//        //设置分页信息
//        page.setPath("/discuss/detail/" + discussPost.getId());
//        page.setRows(discussPost.getCommentCount()); //实体类中有评论的数量
//        page.setLimit(5);
//
//        //使用Map作为vo封装贴子所有的信息用于回显
//        List<Map<String, Object>> commentVoList = new ArrayList<>();
//        final List<Comment> comments = commentService.findCommentsByEntity(ENTITY_TYPE_POST, discussPost.getId(), page.getOffset(), page.getLimit());
//        if (comments != null) {
//
//            for (Comment comment : comments) {
//                //设置相关信息
//                Map<String, Object> commentVo = new HashMap<>();
//                commentVo.put("comment", comment);
//                //单独的每条评论的用户信息
//                commentVo.put("user", userService.selectById(comment.getUserId()));
//
//                //每条评论也有一堆的回复信息
//                List<Map<String, Object>> replyVos = new ArrayList<>();
//
//                //为了让所有的评论都显示，不进行限制
//                final List<Comment> replys = commentService.findCommentsByEntity(ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);
//                if (replys != null) {
//                    for (Comment reply : replys) {
//                        Map<String, Object> replyVo = new HashMap<>();
//                        replyVo.put("reply", reply);
//                        replyVo.put("user", userService.selectById(reply.getUserId()));
//
//                        //设置回复目标，只有恢复的评论才有回复目标，当然也有可能没有目标？
//                        //确实有这种情况：为了避免套娃，在回复中会使用@xxx而不是继续叠加子列表，这样有@的就是有目标的，没有@的就是0
//                        final User target = reply.getTargetId() == 0 ? null : userService.selectById(reply.getTargetId());
//                        replyVo.put("target", target);
//
//                        replyVos.add(replyVo);
//                    }
//                }
//
//                commentVo.put("replys", replyVos);
//
//                final int replyCount = commentService.findCountCommentsByEntity(ENTITY_TYPE_COMMENT, comment.getId());
//                commentVo.put("replyCount", replyCount);
//                commentVoList.add(commentVo);
//            }
//        }
//        model.addAttribute("comments", commentVoList);
//        return "/site/discuss-detail";
//    }

    @Autowired
    LikeService likeService;

    @RequestMapping(path = "/detail/{discussPostId}", method = RequestMethod.GET)
    public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {
        // 帖子
        DiscussPost post = discussPostService.findDiscussPostById(discussPostId);
        model.addAttribute("post", post);
        // 作者
        User user = userService.findUserById(post.getUserId());
        model.addAttribute("user", user);
        // 点赞数量
        long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, discussPostId);
        model.addAttribute("likeCount", likeCount);
        // 点赞状态
        int likeStatus = hostHolder.getUser() == null ? 0 :
                likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_POST, discussPostId);
        model.addAttribute("likeStatus", likeStatus);

        // 评论分页信息
        page.setLimit(5);
        page.setPath("/discuss/detail/" + discussPostId);
        page.setRows(post.getCommentCount());

        // 评论: 给帖子的评论
        // 回复: 给评论的评论
        // 评论列表
        List<Comment> commentList = commentService.findCommentsByEntity(
                ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit());
        // 评论VO列表
        List<Map<String, Object>> commentVoList = new ArrayList<>();
        if (commentList != null) {
            for (Comment comment : commentList) {
                // 评论VO
                Map<String, Object> commentVo = new HashMap<>();
                // 评论
                commentVo.put("comment", comment);
                // 作者
                commentVo.put("user", userService.findUserById(comment.getUserId()));
                // 点赞数量
                likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, comment.getId());
                commentVo.put("likeCount", likeCount);
                // 点赞状态
                likeStatus = hostHolder.getUser() == null ? 0 :
                        likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, comment.getId());
                commentVo.put("likeStatus", likeStatus);

                // 回复列表
                List<Comment> replyList = commentService.findCommentsByEntity(
                        ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);
                // 回复VO列表
                List<Map<String, Object>> replyVoList = new ArrayList<>();
                if (replyList != null) {
                    for (Comment reply : replyList) {
                        Map<String, Object> replyVo = new HashMap<>();
                        // 回复
                        replyVo.put("reply", reply);
                        // 作者
                        replyVo.put("user", userService.findUserById(reply.getUserId()));
                        // 回复目标
                        User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());
                        replyVo.put("target", target);
                        // 点赞数量
                        likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, reply.getId());
                        replyVo.put("likeCount", likeCount);
                        // 点赞状态
                        likeStatus = hostHolder.getUser() == null ? 0 :
                                likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, reply.getId());
                        replyVo.put("likeStatus", likeStatus);

                        replyVoList.add(replyVo);
                    }
                }
                commentVo.put("replys", replyVoList);

                // 回复数量
                int replyCount = commentService.findCountCommentsByEntity(ENTITY_TYPE_COMMENT, comment.getId());
                commentVo.put("replyCount", replyCount);

                commentVoList.add(commentVo);
            }
        }

        model.addAttribute("comments", commentVoList);


        return "/site/discuss-detail";
    }


    @PostMapping("/delete")
    @ResponseBody
    public String setBlack(int id) {
        discussPostService.updateStatus(id,2);
        //更新之后需要记得同步到ES中

        //删帖之后，不应该重新发到ES中，应当从ES中移除
        Event event = new Event()
                .setTopic(TOPIC_DELETE)
                .setEntityType(ENTITY_TYPE_POST)
                .setEntityId(id)
                .setEntityType(ENTITY_TYPE_POST)
                .setUserId(hostHolder.getUser().getId());
        eventProducer.send(event);

        return CommunityUtils.toJsonString(0);
    }

    @PostMapping("/wonderful")
    @ResponseBody
    public String setWonderful(int id) {
        discussPostService.updateStatus(id,1);
        //更新之后需要记得同步到ES中

        //重新发帖即可
        Event event = new Event()
                .setTopic(TOPIC_PUBLISH)
                .setEntityType(ENTITY_TYPE_POST)
                .setEntityId(id)
                .setEntityType(ENTITY_TYPE_POST)
                .setUserId(hostHolder.getUser().getId());
        eventProducer.send(event);

        //帖子得分增加
        String postScoreKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(postScoreKey, id);

        return CommunityUtils.toJsonString(0);
    }

    @PostMapping("/top")
    @ResponseBody
    public String setTop(int id) {
        discussPostService.updateType(id,1);
        //更新之后需要记得同步到ES中

        //重新发帖即可
        Event event = new Event()
                .setTopic(TOPIC_PUBLISH)
                .setEntityType(ENTITY_TYPE_POST)
                .setEntityId(id)
                .setEntityType(ENTITY_TYPE_POST)
                .setUserId(hostHolder.getUser().getId());
        eventProducer.send(event);

        return CommunityUtils.toJsonString(0);
    }
}
